﻿using Action = Styx.TreeSharp.Action;
using Styx;
using Styx.Common;
using Styx.CommonBot;
using Styx.CommonBot.Routines;
using Styx.TreeSharp;
using Styx.WoWInternals;
using Styx.WoWInternals.WoWObjects;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Threading;
using System.Windows.Media;

namespace Kitty
{
    public partial class Main : CombatRoutine
    {
        Color normal = Colors.Yellow;
        Color pull = Colors.CornflowerBlue;
        Color aoe = Colors.LightBlue;
        Color inform = Colors.ForestGreen;
        Color warning = Colors.Red;
        Color buffie = Colors.BlanchedAlmond;
        Color bearform = Colors.Orange;

        #region spells Cat
        Composite SavageRoar()
        {
            return new Decorator(ret => gotTarget
                && SpellManager.HasSpell("Savage Roar")
                && LastSpell != "Savage Roar"
                && (!buffExists("Savage Roar", Me)
                && Me.ComboPoints == 0
                && CRSettings.myPrefs.SavageryGlyph
                && Me.EnergyPercent >= 25)
                || (!buffExists("Savage Roar", Me)
                && Me.ComboPoints > 0
                && Me.EnergyPercent >= 25),
                new Action(ret =>
                {
                    if (SpellManager.CanCast("Savage Roar") && !Me.IsCasting)
                    {
                        SpellManager.Cast("Savage Roar", Me);
                        Logging.Write(normal, "Savage Roar");
                        LastSpell = "Savage Roar";
                    }
                }));
        }
        Composite FerociousBite()
        {
            return new Decorator(ret => gotTarget
                && SpellManager.HasSpell("Ferocious Bite")
                && LastSpell != "Ferocious Bite"
                && ((!SpellManager.HasSpell("Rip") || !IsWoWBoss(Me.CurrentTarget))
                && Me.ComboPoints >= 3
                && Me.EnergyPercent >= 25)
                || (IsWoWBoss(Me.CurrentTarget) 
                && debuffExists("Rip", Me.CurrentTarget)
                && debuffTimeLeft("Rip", Me.CurrentTarget) >= 5000
                && Me.ComboPoints >= 5
                && Me.EnergyPercent >= 25),
                new Action(ret =>
                {
                    if (SpellManager.CanCast("Ferocious Bite") && !Me.IsCasting)
                    {
                        SpellManager.Cast("Ferocious Bite", Me.CurrentTarget);
                        Logging.Write(normal, "Ferocious Bite");
                        LastSpell = "Ferocious Bite";
                    }
                    return RunStatus.Failure;
                }));
        }
        Composite Rake()
        {
            return new Decorator(ret => gotTarget
                    && SpellManager.HasSpell("Rake")
                    && LastSpell != "Rake"
                    && !debuffExists("Rake", Me.CurrentTarget)
                    && Me.EnergyPercent >= 35,
                new Action(ret =>
                {
                    if (SpellManager.CanCast("Rake") && !Me.IsCasting)
                    {
                        SpellManager.Cast("Rake", Me.CurrentTarget);
                        Logging.Write(normal, "Rake");
                        LastSpell = "Rake";
                    }
                    return RunStatus.Failure;
                }));
        }
        Composite Rip()
        {
            return new Decorator(ret => gotTarget
                    && SpellManager.HasSpell("Rip")
                    && LastSpell != "Rip"
                    && !debuffExists(RIP, Me.CurrentTarget)
                    && Me.EnergyPercent >= 30
                    && Me.ComboPoints >= 5
                    && IsWoWBoss(Me.CurrentTarget),
                new Action(ret =>
                {
                    if (SpellManager.CanCast("Rip") && !Me.IsCasting)
                    {
                        SpellManager.Cast("Rip", Me.CurrentTarget);
                        Logging.Write(normal, "Rip");
                        LastSpell = "Rip";
                    }
                    return RunStatus.Failure;
                }));
        }
        Composite Thrash()
        {
            return new Decorator(ret => gotTarget
                    && SpellManager.HasSpell("Thrash")
                    && LastSpell != "Thrash"
                    && !debuffExists("Thrash", Me.CurrentTarget)
                    && buffExists("Clearcasting", Me),
                new Action(ret =>
                {
                    if (SpellManager.CanCast("Thrash") && !Me.IsCasting)
                    {
                        SpellManager.Cast("Thrash", Me.CurrentTarget);
                        Logging.Write(normal, "Thrash");
                        LastSpell = "Thrash";
                    }
                    return RunStatus.Failure;
                }));
        }
        Composite WildCharge()
        {
            return new Decorator(ret => gotTarget
                    && SpellManager.HasSpell("Wild Charge")
                    && !spellOnCooldown("Wild Charge")
                    && targetDistanceBetween(8, 25),
                new Action(ret =>
                {
                    if (SpellManager.CanCast("Wild Charge") && !Me.IsCasting)
                    {
                        SpellManager.Cast("Wild Charge", Me.CurrentTarget);
                        Logging.Write(normal, "Wild Charge");
                        LastSpell = "Wild Charge";
                    }
                    return RunStatus.Failure;
                }));
        }
        Composite PredatoryHeal()
        {
            return new Decorator(ret => gotTarget
                && SpellManager.HasSpell("Healing Touch")
                && LastSpell != "Healing Touch"
                && buffExists("Predatory Swiftness", Me)
                && buffTimeLeft("Predatory Swiftness", Me) >= 2000,
                new Action(ret => 
                {
                    if (SpellManager.CanCast("Healing Touch") 
                        && CRSettings.myPrefs.predatoryHeal 
                        && Me.HealthPercent >= CRSettings.myPrefs.predatoryPercent
                        && (Me.GroupInfo.IsInParty || Me.GroupInfo.IsInRaid || Me.IsInInstance)
                        && !Me.IsCasting)
                    {
                        WoWUnit healTarget = GetHealTarget(40);

                        SpellManager.Cast("Healing Touch", healTarget);
                        Logging.Write(warning, "Healing Touch on " + healTarget);
                        LastSpell = "Healing Touch";
                    }
                    else
                    {
                        if (SpellManager.CanCast("Healing Touch") 
                            && !Me.IsCasting)
                        {
                            SpellManager.Cast("Healing Touch", Me);
                            Logging.Write(warning, "Healing Touch on MySelf");
                            LastSpell = "Healing Touch";
                        }
                    }
                    return RunStatus.Failure;
                }));
        }
        Composite CatForm()
        {
            return new Decorator(ret => gotTarget
                    && Me.Shapeshift != ShapeshiftForm.Cat,
                new Action(ret =>
                    {
                        if (SpellManager.CanCast("Cat Form") && !Me.IsCasting)
                        {
                            SpellManager.Cast("Cat Form", Me);
                            Logging.Write(buffie, "Cat Form");
                            LastSpell = "Cat Form";
                        }
                    }));
        }
        Composite SkullBash()
        {
            return new Decorator(ret => gotTarget
                    && SpellManager.HasSpell("Skull Bash")
                    && CRSettings.myPrefs.interrupt
                    && !spellOnCooldown("Skull Bash")
                    && (Me.CurrentTarget.IsCasting
                    && Me.CanInterruptCurrentSpellCast)
                    && LastSpell != "Mighty Bash"
                    && LastSpell != "Skull Bash",
                new Action(ret =>
                {
                    if (SpellManager.CanCast("Skull Bash")
                            && !Me.IsCasting)
                    {
                        SpellManager.Cast("Skull Bash", Me.CurrentTarget);
                        Logging.Write(normal, "Skull Bash");
                        LastSpell = "Skull Bash";
                    }
                    return RunStatus.Failure;
                }));
        }
        Composite MightyBash()
        {
            return new Decorator(ret => gotTarget
                    && SpellManager.HasSpell("Mighty Bash")
                    && CRSettings.myPrefs.interrupt
                    && !spellOnCooldown("Mighty Bash")
                    && (Me.CurrentTarget.IsCasting
                    && Me.CanInterruptCurrentSpellCast)
                    && LastSpell != "Skull Bash"
                    && LastSpell != "Mighty Bash",
                new Action(ret =>
                {
                    if (SpellManager.CanCast("Mighty Bash")
                            && !Me.IsCasting)
                    {
                        SpellManager.Cast("Mighty Bash", Me.CurrentTarget);
                        Logging.Write(normal, "Mighty Bash");
                        LastSpell = "Mighty Bash";
                    }
                    return RunStatus.Failure;
                }));
        }
        Composite TigersFury()
        {
            return new Decorator(ret => gotTarget
                    && SpellManager.HasSpell("Tiger's Fury")
                    && !buffExists("Berserk", Me)
                    && Me.EnergyPercent <= 30
                    && LastSpell != "Tiger's Fury"
                    && LastSpell != "Lifeblood",
                new Action(ret =>
                {
                    if (SpellManager.CanCast("Tiger's Fury")
                            && !Me.IsCasting)
                    {
                        SpellManager.Cast("Tiger's Fury");
                        Logging.Write(normal, "Tiger's Fury");
                        LastSpell = "Tiger's Fury";
                    }
                    return RunStatus.Failure;
                }));
        }
        Composite Faerie()
        {
            return new Decorator(ret => gotTarget
                && LastSpell != "Faerie Fire"
                && !debuffExists("Weakened Armor", Me.CurrentTarget),
                new Action(ret =>
                {
                    if (SpellManager.HasSpell("Faerie Swarm")
                        && !spellOnCooldown("Faerie Swarm")
                        && SpellManager.CanCast("Faerie Swarm")
                        && !Me.IsCasting)
                    {
                        SpellManager.Cast("Faerie Swarm", Me.CurrentTarget);
                        Logging.Write(normal, "Faerie Swarm");
                        LastSpell = "Faerie Fire";
                    }
                    else
                    {
                        if (SpellManager.HasSpell("Faerie Fire")
                            && !SpellManager.HasSpell("Faerie Swarm")
                            && !spellOnCooldown("Faerie Fire")
                            && SpellManager.CanCast("Faerie Fire")
                            && !Me.IsCasting)
                        {
                            SpellManager.Cast("Faerie Fire", Me.CurrentTarget);
                            Logging.Write(normal, "Faerie Fire");
                            LastSpell = "Faerie Fire";
                        }
                    }
                    return RunStatus.Failure;
                }));
        }
        Composite Berserk()
        {
            return new Decorator(ret => gotTarget
                    && SpellManager.HasSpell("Berserk")
                    && !spellOnCooldown("Berserk")
                    && ((CRSettings.myPrefs.useBerserk == CRSettings.CooldownPrefs.OnCoolDown && targetExistence(Me.CurrentTarget) >= 15 && !IsWoWBoss(Me.CurrentTarget))
                    || (CRSettings.myPrefs.useBerserk == CRSettings.CooldownPrefs.Bosses && IsWoWBoss(Me.CurrentTarget)))
                    && LastSpell != "Berserk",
                new Action(ret =>
                {
                    if (SpellManager.CanCast("Berserk") && !Me.IsCasting)
                    {
                        SpellManager.Cast("Berserk");
                        Logging.Write(normal, "Berserk");
                        LastSpell = "Berserk";
                    }
                    return RunStatus.Failure;
                }));
        }
        Composite Berserking()
        {
            return new Decorator(ret => gotTarget
                    && SpellManager.HasSpell("Berserking")
                    && (CRSettings.myPrefs.berserking == CRSettings.CooldownPrefs.OnCoolDown
                    || (CRSettings.myPrefs.berserking == CRSettings.CooldownPrefs.Bosses && IsWoWBoss(Me.CurrentTarget)))
                    && LastSpell != "Berserking",
                new Action(ret =>
                {
                    if (SpellManager.CanCast("Berserking") && !Me.IsCasting)
                    {
                        SpellManager.Cast("Berserking");
                        Logging.Write(normal, "Berserking");
                        LastSpell = "Berserking";
                    }
                    return RunStatus.Failure;
                }));
        }
        Composite Trinket1()
        {
            return new Decorator(ret => gotTarget
                    && (CRSettings.myPrefs.trinket1 == CRSettings.CooldownPrefs.OnCoolDown
                    || (CRSettings.myPrefs.trinket1 == CRSettings.CooldownPrefs.Bosses && IsWoWBoss(Me.CurrentTarget)))
                    && Me.CurrentTarget.IsWithinMeleeRange
                    && LastSpell != "trinket1"
                    && LastSpell != "trinket2",
                new Action(ret =>
                {
                    var firstTrinket = StyxWoW.Me.Inventory.Equipped.Trinket1;

                    if (firstTrinket != null && CanUseEquippedItem(firstTrinket))
                    {
                        firstTrinket.Use();
                        Logging.Write(inform, "Using 1st trinket");
                        LastSpell = "trinket1";
                    }
                    return RunStatus.Failure;
                }));
        }
        Composite Trinket2()
        {
            return new Decorator(ret => gotTarget
                    && (CRSettings.myPrefs.trinket2 == CRSettings.CooldownPrefs.OnCoolDown
                    || (CRSettings.myPrefs.trinket2 == CRSettings.CooldownPrefs.Bosses && IsWoWBoss(Me.CurrentTarget)))
                    && Me.CurrentTarget.IsWithinMeleeRange
                    && LastSpell != "trinket1"
                    && LastSpell != "trinket2",
                new Action(ret =>
                {
                    var secondTrinket = StyxWoW.Me.Inventory.Equipped.Trinket2;

                    if (secondTrinket != null && CanUseEquippedItem(secondTrinket))
                    {
                        secondTrinket.Use();
                        Logging.Write(inform,"Using 2nd trinket");
                        LastSpell = "trinket2";
                    }
                    return RunStatus.Failure;
                }));
        }
        Composite Gloves()
        {
            return new Decorator(ret => gotTarget
                    && ((CRSettings.myPrefs.gloves == CRSettings.CooldownPrefs.OnCoolDown && targetExistence(Me.CurrentTarget) >= 30 && !IsWoWBoss(Me.CurrentTarget))
                    || (CRSettings.myPrefs.gloves == CRSettings.CooldownPrefs.Bosses && IsWoWBoss(Me.CurrentTarget)))
                    && Me.CurrentTarget.IsWithinMeleeRange
                    && LastSpell != "gloves",
                new Action(ret =>
                {
                    var engiGloves = StyxWoW.Me.Inventory.Equipped.Hands;

                    if (engiGloves != null && CanUseEquippedItem(engiGloves))
                    {
                        engiGloves.Use();
                        Logging.Write(inform,"Using Engineer Gloves");
                        LastSpell = "gloves";
                    }
                    return RunStatus.Failure;
                }));
        }
        Composite StatsPotion()
        {
            return new Decorator(ret => gotTarget
                    && ((CRSettings.myPrefs.virmenpotion == CRSettings.PotionsPrefs.Bosses_All && IsWoWBoss(Me.CurrentTarget))
                    || (CRSettings.myPrefs.virmenpotion == CRSettings.PotionsPrefs.Bosses_Raid_Only && IsWoWBoss(Me.CurrentTarget) && Me.GroupInfo.IsInRaid))
                    && buffExists("Berserk", Me)
                    && Me.CurrentTarget.IsWithinMeleeRange
                    && LastSpell != "virmen",
                new Action(ret =>
                {
                    WoWItem potion = Me.BagItems.FirstOrDefault(h => h.Entry == 76089);


                    if (potion != null && potion.CooldownTimeLeft.TotalMilliseconds <= 0)
                    {
                        potion.Use();
                        Logging.Write(Colors.BlanchedAlmond, "Using " + potion.Name);
                        LastSpell = "virmen";
                    }
                    return RunStatus.Failure;
                }));
        }
        Composite Incarnation()
        {
            return new Decorator( ret => gotTarget
                    && SpellManager.HasSpell("Incarnation")
                    && !spellOnCooldown("Incarnation")
                    && ((CRSettings.myPrefs.useIncarnation == CRSettings.CooldownPrefs.OnCoolDown && targetExistence(Me.CurrentTarget) >= 30 && !IsWoWBoss(Me.CurrentTarget))
                    || (CRSettings.myPrefs.useIncarnation == CRSettings.CooldownPrefs.Bosses && IsWoWBoss(Me.CurrentTarget)))
                    && Me.CurrentTarget.IsWithinMeleeRange
                    && LastSpell != "Incarnation",
                new Action(ret =>
                {
                    if (SpellManager.CanCast("Incarnation") && !Me.IsCasting)
                    {
                        SpellManager.Cast("Incarnation");
                        Logging.Write(normal, "Incarnation");
                        LastSpell = "Incarnation";
                    }
                    return RunStatus.Failure;
                }));
        }
        Composite Ravage()
        {
            return new Decorator(ret => gotTarget
                    && SpellManager.HasSpell("Ravage")
                    && buffExists("Incarnation: King of the Jungle", Me)
                    && Me.EnergyPercent >= 45,
                new Action(ret =>
                {
                    if (SpellManager.CanCast("Ravage") && !Me.IsCasting)
                    {
                        SpellManager.Cast("Ravage", Me.CurrentTarget);
                        Logging.Write(normal, "Ravage");
                        LastSpell = "Ravage";
                    }
                    return RunStatus.Failure;
                }));
        }
        Composite Shred()
        {
            return new Decorator(ret => gotTarget
                    && SpellManager.HasSpell("Shred")
                    && CRSettings.myPrefs.shred
                    && (debuffExists("Rake", Me.CurrentTarget)
                    || debuffExists("Thrash", Me.CurrentTarget))
                    && Me.EnergyPercent >= 40
                    && (Me.IsSafelyBehind(Me.CurrentTarget) || (CRSettings.myPrefs.ShredGlyph && (buffExists("Tiger's Fury", Me) || buffExists("Berserk", Me)))),
                new Action(ret =>
                {
                    if (SpellManager.CanCast("Shred") && !Me.IsCasting)
                    {
                        SpellManager.Cast("Shred", Me.CurrentTarget);
                        Logging.Write(normal, "Shred");
                        LastSpell = "Shred";
                    }
                    return RunStatus.Failure;
                }));
        }
        Composite Lifeblood()
        {
            return new Decorator(ret => gotTarget
                    && SpellManager.HasSpell("Lifeblood")
                    && !spellOnCooldown("Lifeblood")
                    && !buffExists("Tiger's Fury", Me)
                    && ((CRSettings.myPrefs.lifeblood == CRSettings.CooldownPrefs.OnCoolDown && Me.EnergyPercent <= 25 && targetExistence(Me.CurrentTarget) >= 20 && !IsWoWBoss(Me.CurrentTarget))
                    || (CRSettings.myPrefs.lifeblood == CRSettings.CooldownPrefs.Bosses && IsWoWBoss(Me.CurrentTarget) && Me.EnergyPercent <= 25))
                    && LastSpell != "Lifeblood",
                new Action(ret =>
                {
                    if (SpellManager.CanCast("Lifeblood") && !Me.IsCasting)
                    {
                        SpellManager.Cast("Lifeblood", Me.CurrentTarget);
                        Logging.Write(normal, "Lifeblood");
                        LastSpell = "Lifeblood";
                    }
                    return RunStatus.Failure;
                }));
        }
        Composite Mangle()
        {
            return new Decorator(et => gotTarget
                    && SpellManager.HasSpell("Mangle")
                    && Me.EnergyPercent >= 35,
                new Action(ret =>
                {
                    if (SpellManager.CanCast("Mangle") && !Me.IsCasting)
                    {
                        SpellManager.Cast("Mangle", Me.CurrentTarget);
                        Logging.Write(normal, "Mangle");
                        LastSpell = "Mangle";
                    }
                    return RunStatus.Failure;
                }));
        }
        Composite Swipe()
        {
            return new Decorator(ret => gotTarget
                    && SpellManager.HasSpell("Swipe")
                    && Me.EnergyPercent >= 45,
                new Action(ret =>
                {
                    if (SpellManager.CanCast("Swipe") && !Me.IsCasting)
                    {
                        SpellManager.Cast("Swipe", Me.CurrentTarget);
                        Logging.Write(normal, "Swipe");
                        LastSpell = "Swipe";
                    }
                    return RunStatus.Failure;
                }));
        }
        #endregion spells Cat

        #region spells bearform
        Composite BearForm()
        {
            return new Decorator(ret => gotTarget
                    && Me.Shapeshift != ShapeshiftForm.Bear,
                new Action(ret =>
                {
                    if (SpellManager.CanCast("Bear Form") && !Me.IsCasting)
                    {
                        SpellManager.Cast("Bear Form", Me);
                        Logging.Write(bearform, "Bear Form");
                        LastSpell = "Bear Form";
                    }
                    return RunStatus.Failure;
                }));
        }
        Composite Maul()
        {
            return new Decorator(ret => gotTarget
                    && SpellManager.HasSpell("Maul")
                    && Me.RagePercent >= 35,
                new Action(ret =>
                {
                    if (SpellManager.CanCast("Maul") && !Me.IsCasting)
                    {
                        SpellManager.Cast("Maul", Me.CurrentTarget);
                        Logging.Write(bearform, "Maul");
                        LastSpell = "Maul";
                    }
                    return RunStatus.Failure;
                }));
        }
        Composite MangleBear()
        {
            return new Decorator(ret => gotTarget
                    && SpellManager.HasSpell("Mangle")
                    && !spellOnCooldown("Mangle"),
                new Action(ret =>
                {
                    if (SpellManager.CanCast("Mangle") && !Me.IsCasting)
                    {
                        SpellManager.Cast("Mangle", Me.CurrentTarget);
                        Logging.Write(bearform, "Mangle");
                        LastSpell = "Mangle";
                    }
                    return RunStatus.Failure;
                }));
        }
        Composite ThrashBear()
        {
            return new Decorator(ret => gotTarget
                    && SpellManager.HasSpell("Thrash")
                    && !debuffExists("Thrash", Me.CurrentTarget)
                    && !spellOnCooldown("Thrash"),
                new Action(ret =>
                {
                    if (SpellManager.CanCast("Thrash") && !Me.IsCasting)
                    {
                        SpellManager.Cast("Thrash", Me.CurrentTarget);
                        Logging.Write(bearform, "Thrash");
                        LastSpell = "Thrash";
                    }
                    return RunStatus.Failure;
                }));
        }
        Composite SwipeBear()
        {
            return new Decorator(ret => gotTarget
                    && SpellManager.HasSpell("Swipe")
                    && !PauseAoe
                    && addCount > 1
                    && Me.RagePercent >= 15,
                new Action(ret =>
                {
                    if (SpellManager.CanCast("Swipe") && !Me.IsCasting)
                    {
                        SpellManager.Cast("Swipe", Me.CurrentTarget);
                        Logging.Write(bearform, "Swipe");
                        LastSpell = "Swipe";
                    }
                    return RunStatus.Failure;
                }));
        }
        Composite Lacerate()
        {
            return new Decorator(ret => gotTarget
                    && SpellManager.HasSpell("Lacerate"),
                new Action(ret =>
                {
                    if (SpellManager.CanCast("Lacerate") && !Me.IsCasting)
                    {
                        SpellManager.Cast("Lacerate", Me.CurrentTarget);
                        Logging.Write(bearform, "lacerate");
                        LastSpell = "Lacerate";
                    }
                    return RunStatus.Failure;
                }));
        }
        #endregion spells Bearform
    }
}
